package com.hc.radius.command;

import java.util.ArrayList;
import java.util.List;

import com.hc.radius.service.Const;
import com.hc.util.Util;

public class CommandWrap {

	public static Class lognCmd = LoginCommand.class;
	public static Class logoutCmd = LogoutCommand.class;
	public static Class quCmd = QueryUserCommand.class;
	public static Class qoCmd = QueryOrderCommand.class;
	public static Class qusCmd = QueryUserSessCommand.class;
	
	
	public static byte[] wrap(Command cmd, CommandParam cmdp) {
		if (cmd == null || cmdp == null) {
			return null;
		}
		
		List<Byte> list = new ArrayList<Byte>();
		addByte(list, Const.MSG_START_TAG);
		// 添加消息长度 4B
		int len = cmd.getLen(cmdp);
		addHexLen(list, len);

		// 添加消息头= 版本号(4B)＋终端标识(8B) ＋服务名(8B)
		addByte(list, cmd.version, cmd.terminal, cmd.servicename);

		// 添加会话头 =会话 ID(8B)＋会话控制字(6B)＋会话保留字(4B
		addByte(list, cmd.sessionid, cmd.sessionCtrl, cmd.sessionrsvd);

		// 添加事务头＝事务 ID(8B)＋事务控制字(6B)＋事务保留字(4B
		addByte(list, cmd.transid, cmd.transCtrl, cmd.transrsvd);

		// 添加消息内容（4N * B)
		cmd.addCmdContent(list, cmdp);

		addCheckout(list);
		return Util.encode(list);
	}

	public static byte[] wrap(Class<Command> clazz, CommandParam cmdp) {
		Command cmd = CommandCreater.cc.creater(clazz);
		return wrap(cmd, cmdp);
	}

	public static byte[] wrap(String className, CommandParam cmdp) {
		Command cmd = CommandCreater.cc.creater(className);
		return wrap(cmd, cmdp);
	}

	// 添加校验码 4B
	private static void addCheckout(List<Byte> list) {
		byte[] res = new byte[4];
		for (int i = 8; i < list.size(); i += 4) {
			res[0] ^= list.get(i);// (buf+i)[0];
			res[1] ^= list.get(i + 1);// (buf+i)[1];
			res[2] ^= list.get(i + 2);// (buf+i)[2];
			res[3] ^= list.get(i + 3);// (buf+i)[3];
		}
		res[0] = (byte) ~res[0];
		res[1] = (byte) ~res[1];
		res[2] = (byte) ~res[2];
		res[3] = (byte) ~res[3];
		addByte(list,res);
	}
	

	public static void addTail(List<Byte> list, int len) {
		while (len % 4 != 0) {
			len++;
			list.add((byte) 32);
		}
		len = 0;
		while (len < 4) {
			len++;
			list.add((byte) 32);
		}
	}

	public static void addHexLen(List<Byte> list, int len) {
		while (len % 4 != 0) {
			len++;
		}
		String hexLen = Integer.toHexString(len);
		int hl = hexLen.length();
		while (hl < 4) {
			hl++;
			hexLen = "0" + hexLen;
		}

		List<Byte> bytes = Util.toByte(Util.toHexString(hexLen));
		list.addAll(bytes);
	}
	
	public static void addByte(List<Byte> list, byte[]... bytes) {
		for (byte[] bytes_ : bytes) {
			for (byte b : bytes_) {
				list.add(b);
			}
		}
	}
}
